package com.hadoop.util;

import java.util.List;

public class MathUtil {

    /**
     *  计算方差!
     * @param list
     * @return
     */
    public static double Variance(List<Double> list){
        return Variance(list.toArray(new Double[0]));
    }

    /**
     *  计算一组数据的标准差!
     * @param list
     * @return
     */
    public static double StandardDeviation(List<Double> list){
        return StandardDeviation(list.toArray(new Double[0]));
    }


    /**
     *  求两组数据的回归率!
     * @param list1
     * @param list2
     * @return
     */
    public static double getBalance(List<Double> list1,List<Double> list2){
        if(list1.size() >= list2.size()) return getBalance(list2.toArray(new Double[0]),list1.toArray(new Double[0]),list2.size());
        return getBalance(list1.toArray(new Double[0]),list2.toArray(new Double[0]),list1.size());
    }



    /**
     *  指定迭代次数,对结果进行预测!
     * @param list 给定的数据!
     * @param x 迭代次数认为指定!
     * @return 返回预测结果!
     */
    public static double WeightedMovingAverage(List<Double> list,int x){
        return WeightedMovingAverage(list.toArray(new Double[0]),x);
    }





    private static double Variance(Double[] x) {
        int m = x.length;
        double sum = 0;
        for (int i = 0; i < m; i++) {//求和
            sum += x[i];
        }
        double dAve = sum / m;//求平均值
        double dVar = 0;
        for (int i = 0; i < m; i++) {//求方差
            dVar += (x[i] - dAve) * (x[i] - dAve);
        }
        return dVar / m;
    }




    private static double StandardDeviation(Double[] x) {
        int m = x.length;
        double sum = 0;
        for (int i = 0; i < m; i++) {//求和
            sum += x[i];
        }
        double dAve = sum / m;//求平均值
        double dVar = 0;
        for (int i = 0; i < m; i++) {//求方差
            dVar += (x[i] - dAve) * (x[i] - dAve);
        }

        return Math.sqrt(dVar / m);
    }



    private static double getBalance(Double[] x, Double[] y, int min_size) {
        //首先先保证x,y是数量相同的
        double balance = 0;
        //先对x求平均
        double xp = 0;
        double yp = 0;

        for (int i = 0; i < min_size; i++) {
            xp += x[i];
            yp += y[i];
        }
        xp = xp / (double) min_size;
        yp = yp / (double) min_size;

        //第二步
        double xpp = 0;
        double ypp = 0;
        double zpp = 0;
        double xxp = 0;
        for (int k = 0; k < min_size; k++) {
            xpp = (x[k] - xp);
            ypp = (y[k] - yp);
            zpp += (xpp * ypp);
            xxp += (xpp * xpp);
        }

        balance = zpp / xxp;

        return balance;
    }




    private static double WeightedMovingAverage(Double[] data, int x) {
        Double[] newData = data.clone();
        int count = newData.length;
        double ret = 0.0;
        int i = 0;
        while (i <= x) {
            ret = 0.0;
            for (int j = 0; j < count; j++) {
                ret += (j + 1) * newData[j];
            }
            ret /= (count * (count + 1) / 2);
            for (int j = 0; j < count - 1; j++) {
                newData[j] = newData[j + 1];
            }
            newData[count - 1] = ret;

            double nd = newData[newData.length - 1];
            double cs = 0;
            int js = 0;
            for (int h = 0; h < newData.length - 1; h++) {
                cs = newData[h];
                if (nd == cs) {
                    js++;
                }
            }
            if (js == newData.length - 1) {
                break;
            }
            i++;
        }
        return ret;
    }

}
